package models

import (
	"crypto/md5"
	"encoding/hex"
	"errors"
	"log"

	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
)

type User struct {
	Id          int64
	Username    string `orm:"size(100)" form:"username"  valid:"Required"`
	Password    string `orm:"size(32)" form:"Password" valid:"Required;MaxSize(32);MinSize(6)"`
	Role        int64  `form:"role"`
	CreateTs    int64  `form:"create_ts"`
	LastLoginTs int64  `form:"last_login_ts"`
}

func init() {
	orm.RegisterModel(new(User))
}

func (u *User) TableName() string {
	return "tb_user"
}

//验证用户信息
func checkUser(u *User) (err error) {
	valid := validation.Validation{}
	b, _ := valid.Valid(&u)
	if !b {
		for _, err := range valid.Errors {
			log.Println(err.Key, err.Message)
			return errors.New(err.Message)
		}
	}
	return nil
}

func Strtomd5(s string) string {
	h := md5.New()
	h.Write([]byte(s))
	rs := hex.EncodeToString(h.Sum(nil))
	return rs
}

//get user list
func GetUserlist() (users []orm.Params, count int64) {
	o := orm.NewOrm()
	user := new(User)
	qs := o.QueryTable(user)
	qs.Values(&users)
	count, _ = qs.Count()
	return users, count
}

//添加用户
func AddUser(u *User) (int64, error) {
	if err := checkUser(u); err != nil {
		return 0, err
	}
	o := orm.NewOrm()

	id, err := o.Insert(u)
	return id, err
}

//更新用户
func UpdateUser(u *User) (int64, error) {
	if err := checkUser(u); err != nil {
		return 0, err
	}
	o := orm.NewOrm()
	user := make(orm.Params)
	if len(u.Username) > 0 {
		user["Username"] = u.Username
	}
	if len(u.Password) > 0 {
		user["Password"] = u.Password //Strtomd5(u.Password)
	}
	if u.Role != 0 {
		user["Role"] = u.Role
	}
	if u.CreateTs != 0 {
		user["CreateTs"] = u.CreateTs
	}
	if u.LastLoginTs != 0 {
		user["LastLoginTs"] = u.LastLoginTs
	}
	if len(user) == 0 {
		return 0, errors.New("update field is empty")
	}
	var table User
	num, err := o.QueryTable(table).Filter("Id", u.Id).Update(user)
	return num, err
}

func DelUserById(Id int64) (int64, error) {
	o := orm.NewOrm()
	status, err := o.Delete(&User{Id: Id})
	return status, err
}

func GetUserByUsername(username string) (user *User) {
	user = &User{Username: username}
	o := orm.NewOrm()
	err := o.Read(user, "Username")
	if err != nil {
		return nil
	}
	return user
}

func GetUserById(id int64) (user *User) {
	user = &User{Id: id}
	o := orm.NewOrm()
	err := o.Read(user, "Id")
	if err != nil {
		return nil
	}
	return user
}

func GetPermission(username string) int64 {
	user := GetUserByUsername(username)
	if user == nil {
		return 0
	}
	p := GetRoleById(user.Role)
	if p == nil {
		return 0
	}
	return p.Permission
}

//检查用户是否满足权限
func CheckPermission(username string, permission int) bool {
	user := GetUserByUsername(username)
	if user == nil {
		return false
	}
	p := GetRoleById(user.Role)
	if p == nil {
		return false
	}
	return (p.Permission & (1 << uint(permission))) != 0
}
